﻿using BaseUi.Models;
using BaseUi.ViewModel;
using Ping9719.DeviceCommunication;
using Ping9719.DeviceCommunication.Common.Helpers;
using Ping9719.WpfEx;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace BaseUi.Device
{
    public class DianQiBan : Ping9719.DeviceCommunication.SerialPortBase
    {

        static readonly object locklog = new object();
        public string stateCode = "TRIGGER";//开始扫描
        public string endCode = "UNTRIG";//取消扫描
        /// <summary>
        /// 设置继电器
        /// </summary>
        /// <param name="close">闭合通道</param>
        /// <param name="open">断开通道</param>
        /// <param name="addr">485地址</param>
        /// <returns></returns>
        public static byte[] SetChannel(List<int> close, List<int> open, ushort addr)
        {
            int lenH = (13 + close.Count + open.Count) >> 8;
            int lenL = (13 + close.Count + open.Count) & 0xFF;
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, lenH, lenL, addrH, addrL, 0x02, 0x01, 0x01, };
            bytes.Add(close.Count());
            bytes.AddRange(close);
            bytes.Add(open.Count());
            bytes.AddRange(open);
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }
        /// <summary>
        /// 继电器控制气缸全
        /// </summary>
        /// <param name="of">开（2）or关（3）</param>
        /// <param name="addr">485地址</param>
        /// <returns></returns>
        public static byte[] SetChanneall(int of, ushort addr)
        {
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, 0x00, 0x0B, addrH, addrL, 0x02, 0x01, Convert.ToByte(of) };
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }/// <summary>
         /// 读取电平
         /// </summary>
         /// <param name="close">闭合通道</param>
         /// <param name="open">断开通道</param>
         /// <param name="addr">485地址</param>
         /// <returns></returns>
        public static byte[] SetChannerelay(List<int> num, ushort addr)
        {
            int lenH = (11 + num.Count) >> 8;
            int lenL = (11 + num.Count) & 0xFF;
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, lenH, lenL, addrH, addrL, 0x02, 0x03, 0x01, };
            bytes.AddRange(num);
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }
        /// <summary>
        /// 电平
        /// </summary>
        /// <param name="of">开（2）or关（3）</param>
        /// <param name="addr">485地址</param>
        /// <returns></returns>
        public static byte[] SetChannerlevel(int of, ushort addr)
        {
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, 0x00, 0x0B, addrH, addrL, 0x02, 0x03, 0x02 };
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }
        /// <summary>
        /// 触发
        /// </summary>
        /// <param name="of">开（2）or关（3）</param>
        /// <param name="addr">485地址</param>
        /// <returns></returns>
        public static byte[] SetTrigger(ushort addr)
        {
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, 0x00, 0x0D, addrH, addrL, 0x02, 0x03, 0x08, 0x01 };
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }
        /// <summary>
        /// led灯
        /// </summary>
        /// <param name="strike">tongdao</param>
        /// <param name="of">开（1）or关（0）</param>
        /// <param name="addr">485地址</param>
        /// <returns></returns>
        public static byte[] SetChannerled(int strike, int of, ushort addr)
        {
            int addrH = addr >> 8;
            int addrL = addr & 0xFF;
            List<int> bytes = new List<int> { 0x55, 0xAA, 0x00, 0x0D, addrH, addrL, 0x02, 0x06, 0x03, strike, of };
            var order = bytes.ConvertAll<byte>(it => Convert.ToByte(it)).ToArray();
            return Ping9719.DeviceCommunication.Common.Helpers.CRC16.GetCRC16(order);
        }
        /// <summary>
        /// 使用串口的方式
        /// </summary>
        public DianQiBan(string portName, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            if (serialPort == null)
                serialPort = new SerialPort();
            serialPort.PortName = portName;
            serialPort.BaudRate = baudRate;
            serialPort.DataBits = dataBits;
            serialPort.StopBits = stopBits;
            serialPort.Encoding = Encoding.UTF8;
            serialPort.Parity = parity;
        }

        /// <summary>
        /// 在外部触发模式下执行一次
        /// </summary>
        /// <param name="timeout">保持时长（毫秒），填写解码设置：触发超时时间设置的值</param>
        /// <returns></returns>
        public Result<string> ReadOne(int timeout)
        {
            var conn = Connect1();
            if (!conn.IsSucceed)
                return new Result<string>(conn);

            serialPort.ReadTimeout = timeout;
            serialPort.WriteTimeout = timeout;
            var result = new Result<string>();
            try
            {
                //清空字符,还原状态
                serialPort.DiscardInBuffer();
                var send = SetChannel(new List<int> { 1 }, new List<int> { }, 1);
                serialPort.Write(send, 0, send.Length);
                var aaa = SerialPortRead();
                if (!aaa.IsSucceed)
                    return new Result<string>(aaa);

                for (int i = 0; i < aaa.Value.Length; i++)
                {
                    result.Value += aaa.Value[i].ToString("X2");
                }
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err = ex.Message;
            }
            return result.EndTime();
        }
        /// <summary>
        /// 调试模式
        /// </summary>
        /// <param name="timeout">保持时长（毫秒），填写解码设置：触发超时时间设置的值</param>
        /// <returns></returns>
        public Result<string> Readsent(int timeout, string ms)
        {
            var conn = Connect1();
            if (!conn.IsSucceed)
                return new Result<string>(conn);

            serialPort.ReadTimeout = timeout;
            serialPort.WriteTimeout = timeout;
            var result = new Result<string>();
            try
            {
                //清空字符,还原状态
                serialPort.DiscardInBuffer();
                var send = SetChanneall(1, (ushort)Convert.ToInt16(ms));
                lock (locklog)
                {
                    serialPort.Write(send, 0, send.Length);
                    var aaa = SerialPortRead();
                    if (!aaa.IsSucceed)
                        return new Result<string>(aaa);

                    if (!CRC16.CheckCRC16new(aaa.Value))
                    {
                        aaa.IsSucceed = false;
                        aaa.Value = new byte[] { };
                        aaa.Err = "数据CRC16验证不合格";
                        return new Result<string>(aaa); ;
                    }
                    for (int i = 0; i < aaa.Value.Length; i++)
                    {
                        result.Value += aaa.Value[i].ToString("X2");
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err = ex.Message;
            }
            return result.EndTime();
        }
        /// <summary>
        /// 注册事件用来接收触发通信（暂停，启动）
        /// </summary>
        public void s()
        {
            var conn = Connect1();
            serialPort.DataReceived += Serialport_receData;
        }
        private void Serialport_receData(object sender, SerialDataReceivedEventArgs e)
        {
            //homeViewModel.runstart = 1;
            lock (locklog)
            {
                Thread.Sleep(100);
                var aaa = SerialPortRead();
                if (!aaa.IsSucceed)
                {
                    HomeView.viewModel.AddTempTextErr("电气通信", new string[] { "错误" });
                }
                if (aaa.Value != null)
                {
                    if (aaa.Value.Length == 0)
                    {
                        return;
                    }
                    string rest = "";
                    //string rest1 = "";
                    for (int i = 0; i < aaa.Value.Length; i++)
                    {
                        rest += aaa.Value[i].ToString("X2") + " ";
                    }
                    //var send = SetTrigger( LocalFile.Config.Address);
                    if (aaa.Value.Length != 13)
                    {
                        TextBoxLog.AddLog("长度错误");
                        return;
                    }

                    if (!CRC16.CheckCRC16new(aaa.Value))
                    {
                        aaa.IsSucceed = false;
                        aaa.Value = new byte[] { };
                        aaa.Err = "数据CRC16验证不合格";
                        return;
                    }
                    //for (int i = 0; i < aaa.Value.Length; i++)
                    //{
                    //    //result.Value += aaa.Value[i].ToString("X2");
                    //    //if (i < 9 && aaa.Value[i] != send[i])
                    //    //{
                    //    //    TextBoxLog.AddLog(rest1+"前段第"+(i+1).ToString()+"错误");
                    //    //    return;
                    //    //}

                    //    if (i >= 9&&i< aaa.Value.Length-2)
                    //    {
                    //        rest += aaa.Value[i].ToString("X2")+" ";
                    //    }
                    //}
                    if (rest == PortModel.button)
                    {
                        HomeView.viewModel.AddTempTextErr("按钮", new string[] { "急停按钮暂停" });
                        //HomeView.viewModel.Pause();
                    }
                    else if (rest == PortModel.raster)
                    {
                        //HomeView.viewModel.AddTempTextErr("光栅", new string[] { "光栅暂停" });
                        //HomeView.viewModel.Pause();
                    }
                    else if (rest == PortModel.box)
                    {
                        HomeView.viewModel.AddTempTextErr("关箱", new string[] { "开关箱暂停" });
                        //HomeView.viewModel.Pause();
                    }
                    if (HomeView.viewModel.RunState == RunState.Run)
                    {
                        if (rest == PortModel.start1)
                        {
                            TextBoxLog.AddLog("启动");
                            HomeView.viewModel.runstart = 1;
                        }
                        else if (rest == PortModel.start2)
                        {
                            TextBoxLog.AddLog("强制启动");
                            HomeView.viewModel.runstart = 2;
                        }
                        else if (rest == PortModel.button)
                        {
                            TextBoxLog.AddLog("急停按钮暂停");
                            HomeView.viewModel.Pause();
                        }
                        else if (rest == PortModel.raster)
                        {
                            if (HomeView.viewModel.directioning == true)
                            {
                                HomeView.viewModel.AddTempTextErr("光栅", new string[] { "光栅暂停" });
                                TextBoxLog.AddLog("光栅暂停");
                                //HomeView.viewModel.Pause();
                            }
                        }
                        else if (rest == PortModel.box)
                        {
                            TextBoxLog.AddLog("开关箱暂停");
                            HomeView.viewModel.Pause();
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 继电器控制
        /// </summary>
        /// <param name="timeout">保持时长（毫秒），填写解码设置：触发超时时间设置的值</param>
        /// <param name="open">开</param>
        /// <param name="down">关</param>
        /// <returns></returns>
        public Result<string> Readsentrelay(int timeout, List<int> down, List<int> open, ushort addr)
        {
            var conn = Connect1();
            if (!conn.IsSucceed)
                return new Result<string>(conn);

            serialPort.ReadTimeout = timeout;
            serialPort.WriteTimeout = timeout;
            var result = new Result<string>();
            try
            {
                //清空字符,还原状态
                serialPort.DiscardInBuffer();
                var send = SetChannel(down, open, addr);
                //for (int i = 0; i < send.Length; i++)
                //{
                //    //result.Value += aaa.Value[i].ToString("X2");

                //    result.Value += send[i].ToString("X2")+" ";
                //}
                lock (locklog)
                {
                    serialPort.Write(send, 0, send.Length);
                    var aaa = SerialPortRead();
                    if (!aaa.IsSucceed)
                        return new Result<string>(aaa);

                    if (aaa.Value == null)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "无信息";
                        return new Result<string>(aaa);
                    }
                    if (aaa.Value.Length != 11)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "长度错误";
                        return new Result<string>(aaa);
                    }
                    //if (!CRC16.CheckCRC16new(aaa.Value))
                    //{
                    //    aaa.IsSucceed = false;
                    //    aaa.Value = new byte[] { };
                    //    aaa.Err = "数据CRC16验证不合格";
                    //    return new Result<string> (aaa);
                    //}
                    //for (int i = 0; i < aaa.Value.Length; i++)
                    //{
                    //    //result.Value += aaa.Value[i].ToString("X2");
                    //    //if (i < 9 && aaa.Value[i] != send[i])
                    //    //{
                    //    //    aaa.IsSucceed = false;
                    //    //    aaa.Err = result.Value + "错误";
                    //    //    return new Result<string>(aaa);
                    //    //}
                    //    //if (i >= 9)
                    //    //{
                    //        result.Value += aaa.Value[i].ToString("X2");
                    //    //}
                    //}
                    for (int i = 0; i < aaa.Value.Length; i++)
                    {
                        result.Value += aaa.Value[i].ToString("X2");
                    }
                    if (result.Value != "55AA000B00000201014F23")
                    {
                        result.IsSucceed = false;
                        result.Err = result.Value;
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err = ex.Message;
            }
            return result.EndTime();
        }
        /// <summary>
        /// 电频检测
        /// </summary>
        /// <param name="timeout">保持时长（毫秒），填写解码设置：触发超时时间设置的值</param>
        /// <param name="num">需要读取的电频</param>
        /// <returns></returns>
        public Result<string> Readsentfrequency(int timeout, List<int> num, ushort addr)
        {
            var conn = Connect1();
            if (!conn.IsSucceed)
                return new Result<string>(conn);
            serialPort.ReadTimeout = timeout;
            serialPort.WriteTimeout = timeout;
            var result = new Result<string>();
            try
            {
                //清空字符,还原状态
                serialPort.DiscardInBuffer();
                var send = SetChannerelay(num, addr);
                //for (int i = 0; i < send.Length; i++)
                //{
                //    //result.Value += aaa.Value[i].ToString("X2");

                //        result.Value += send[i].ToString("X2")+" ";
                //}
                //string d = "d";
                lock (locklog)
                {
                    serialPort.Write(send, 0, send.Length);
                    var aaa = SerialPortRead();
                    if (!aaa.IsSucceed)
                        return new Result<string>(aaa);
                    //result.Value = new string[aaa.Value.Length];
                    if (aaa.Value == null)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "无信息";
                        return new Result<string>(aaa);
                    }
                    if (send.Length != aaa.Value.Length)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "长度错误";
                        return new Result<string>(aaa);
                    }
                    if (!CRC16.CheckCRC16new(aaa.Value))
                    {
                        aaa.IsSucceed = false;
                        aaa.Value = new byte[] { };
                        aaa.Err = "数据CRC16验证不合格";
                        return new Result<string>(aaa);
                    }
                    for (int i = 0; i < aaa.Value.Length; i++)
                    {
                        //result.Value += aaa.Value[i].ToString("X2");
                        if (i < 9 && aaa.Value[i] != send[i])
                        {
                            aaa.IsSucceed = false;
                            aaa.Err = result.Value + "错误";
                            return new Result<string>(aaa);
                        }
                        if (i >= 9 && i < aaa.Value.Length - 2)
                        {
                            result.Value += aaa.Value[i].ToString("X2") + " ";
                        }
                    }
                    //result.Value = Encoding.UTF8.GetString(aaa.Value);
                }
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err = ex.Message;
            }
            return result.EndTime();
        }
        /// <summary>
        /// LED灯
        /// </summary>
        /// <param name="timeout">保持时长（毫秒），填写解码设置：触发超时时间设置的值</param>
        /// <param name="strike">需要开关的LED灯</param>
        /// <param name="of">开(0)关（1）</param>
        /// <returns></returns>
        public Result<string> Readsentled(int timeout, int strike, int of, ushort addr)
        {
            var conn = Connect1();
            if (!conn.IsSucceed)
                return new Result<string>(conn);
            serialPort.ReadTimeout = timeout;
            serialPort.WriteTimeout = timeout;
            var result = new Result<string>();
            try
            {
                //清空字符,还原状态
                serialPort.DiscardInBuffer();
                var send = SetChannerled(strike, of, addr);
                lock (locklog)
                {
                    serialPort.Write(send, 0, send.Length);
                    var aaa = SerialPortRead();
                    if (!aaa.IsSucceed)
                        return new Result<string>(aaa);
                    if (aaa.Value == null)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "无信息";
                        return new Result<string>(aaa);
                    }
                    if (send.Length != aaa.Value.Length)
                    {
                        aaa.IsSucceed = false;
                        aaa.Err = "长度错误";
                        return new Result<string>(aaa);
                    }
                    if (!CRC16.CheckCRC16new(aaa.Value))
                    {
                        aaa.IsSucceed = false;
                        aaa.Value = new byte[] { };
                        aaa.Err = "数据CRC16验证不合格";
                        return new Result<string>(aaa);
                    }
                    for (int i = 0; i < aaa.Value.Length; i++)
                    {
                        if (i < 9 && aaa.Value[i] != send[i])
                        {
                            aaa.IsSucceed = false;
                            aaa.Err = result.Value + "错误";
                            return new Result<string>(aaa);
                        }
                        if (i >= 9 && i < aaa.Value.Length - 2)
                        {
                            result.Value += aaa.Value[i].ToString("X2");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err = ex.Message;
            }
            return result.EndTime();
        }
    }
}
